package com.tarena.lbs.basic.web.repository;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tarena.lbs.basic.web.mapper.StoreMapper;
import com.tarena.lbs.pojo.basic.entity.StoreSearchEntity;
import com.tarena.lbs.pojo.basic.param.UserLocationParam;
import com.tarena.lbs.pojo.basic.po.StorePO;
import com.tarena.lbs.pojo.basic.query.AreaStoreQuery;
import com.tarena.lbs.pojo.basic.query.StoreQuery;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.GeoDistanceQueryBuilder;
import org.elasticsearch.index.query.GeoShapeQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

@Repository
@Slf4j
public class StoreRepository {
    @Autowired
    private StoreMapper storeMapper;
    @Autowired
    private StoreESRepository storeESRepository;
    @Autowired
    private RestHighLevelClient client;
    public PageInfo<StorePO> getStoresByPage(StoreQuery storeQuery) {
        QueryWrapper<StorePO> queryWrapper=new QueryWrapper();
        //storeName 模糊查询
        //storeHeadPhone 负责人电话 相等
        //区域 provinceId cityId areaId 非空时判断相等 where拼接
        if (storeQuery.getBusinessId()!=null){
            //当前查询一定是商家账号查询
            queryWrapper.eq("business_id",storeQuery.getBusinessId());
        }
        //开启分页
        PageHelper.startPage(storeQuery.getPageNo(),storeQuery.getPageSize());
        List<StorePO> pos = storeMapper.selectList(queryWrapper);
        PageInfo<StorePO> pageInfo = new PageInfo<>(pos);
        return pageInfo;
    }

    public void saveStore(StorePO poParam) {
        storeMapper.insert(poParam);
        insertIntoES(poParam);
    }

    private void insertIntoES(StorePO poParam) {
        //1 配置一个RestHighLevelClient 将poParam转化成StoreSearchEntity IndexRequest
        StoreSearchEntity entity=new StoreSearchEntity();
        BeanUtils.copyProperties(poParam,entity);
        entity.setLocation(poParam.getStoreLatitude()+","+poParam.getStoreLongitude());
        //2 使用ElasticsearchRepository直接写入
        storeESRepository.save(entity);
    }

    public PageInfo<StorePO> getStoresByAreasAndBizId(Integer businessId, AreaStoreQuery areaStoreQuery) {
        //封装query查询条件 business_id=#{businessId} and (province_id in or city_id in or area_id in)
        /*QueryWrapper<StorePO> queryWrapper=new QueryWrapper();
        queryWrapper.eq("business_id",businessId);
        queryWrapper.in("province_id",areaStoreQuery.getCityIdList()).
                or().in("city_id",areaStoreQuery.getCityIdList()).
                or().in("area_id",areaStoreQuery.getCityIdList());*/
        PageHelper.startPage(areaStoreQuery.getPageNo(),areaStoreQuery.getPageSize());
        List<StorePO> pos = storeMapper.selectStoresByAreasAndBizId(businessId,areaStoreQuery.getCityIdList());
        return new PageInfo<>(pos);
    }

    public List<StoreSearchEntity> getLocationStores(UserLocationParam param) {
        //使用restHighLevelClient 利用GeoDistanceQuery搜索查询 lbs_store索引中的所有店铺信息
        //1.构造请求对象
        SearchRequest request=new SearchRequest("lbs_store");
        //2.填补请求参数 分页前10条 去重 查询条件等等
        SearchSourceBuilder sourceBuilder=new SearchSourceBuilder();
        sourceBuilder.from(0);
        sourceBuilder.size(10);
        GeoPoint geoPoint=new GeoPoint(Double.valueOf(param.getLatitude()),Double.valueOf(param.getLongitude()));
        GeoDistanceQueryBuilder query = QueryBuilders.geoDistanceQuery("location");
        query.point(geoPoint).distance(50d, DistanceUnit.KILOMETERS);
        sourceBuilder.query(query);
        request.source(sourceBuilder);
        //3.获取请求结果 从es响应中 解析数据
        SearchResponse response =null;
        try{
            response = client.search(request, RequestOptions.DEFAULT);
        }catch (Exception e){
            log.error("定位店铺搜索失败",e);
        }
        //4.返回解析转化结果entities
        if (response!=null){
            //拿到所有响应文档
            SearchHit[] hits = response.getHits().getHits();
            List<StoreSearchEntity> entities=new ArrayList<>();
            if (response.getHits().getTotalHits().value>0){
                for (SearchHit hit : hits) {
                    entities.add(JSON.parseObject(hit.getSourceAsString(),StoreSearchEntity.class));
                }
            }
            return entities;
        }else{
            return null;
        }
        //仓储层的返回结果 有几个可能 null 空集合 有店铺信息的集合

    }

    public List<StorePO> getStoresByBizId(Integer id) {
        //select * from lbs_store where business_id=#{id}
        QueryWrapper<StorePO> queryWrapper=new QueryWrapper();
        queryWrapper.eq("business_id",id);
        return storeMapper.selectList(queryWrapper);
    }
}
